package com.ruoyi.web.controller;

import cn.hutool.core.util.IdUtil;
import cn.hutool.json.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.common.annotation.Anonymous;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.web.config.AliPayConfig;
import com.ruoyi.web.dto.OrdersDto;
import com.ruoyi.web.entity.*;
import com.ruoyi.web.service.IChargingRecordsService;
import com.ruoyi.web.service.ICouponService;
import com.ruoyi.web.service.ICustomerCouponsService;
import com.ruoyi.web.service.IOrdersService;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.math.BigDecimal;
import java.rmi.RemoteException;
import java.util.*;

import static com.ruoyi.common.utils.SecurityUtils.getLoginUser;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author lqc
 * @since 2024-02-02
 */
@RestController
@RequestMapping("/orders")
public class OrdersController {
    private static final String GATEWAY_URL = "https://openapi-sandbox.dl.alipaydev.com/gateway.do";
    private static final String FORMAT = "JSON";
    private static final String CHARSET = "UTF-8";
    private static final String SIGN_TYPE = "RSA2";

    private final IOrdersService ordersServiceImpl;
    private final AliPayConfig aliPayConfig;
    private final IChargingRecordsService chargingRecordsService;
    private final ICouponService couponService;
    private final ICustomerCouponsService customerCouponsService;
    Long chargingRecordsIds = 0L;
    Long couponId = 0L;

    Long userId=0L;


    public OrdersController(IOrdersService ordersServiceImpl, AliPayConfig aliPayConfig, IChargingRecordsService chargingRecordsService, ICouponService couponService, ICustomerCouponsService customerCouponsService) {
        this.ordersServiceImpl = ordersServiceImpl;
        this.aliPayConfig = aliPayConfig;
        this.chargingRecordsService = chargingRecordsService;
        this.couponService = couponService;
        this.customerCouponsService = customerCouponsService;
    }

    @Log(title = "生成订单", businessType = BusinessType.CREATORDERS)
    @PostMapping("/creatOrders")
    public void creatOrders(@RequestBody OrdersDto ordersDto, HttpServletResponse resp) throws IOException {
        if (ordersDto.getId() == null) {
            return;
        }


        chargingRecordsIds = ordersDto.getId();
        Long totalMoney = 0L;
        Orders orders = new Orders();
        long newId = IdUtil.getSnowflakeNextId();
        StringBuilder items = new StringBuilder();
        List<ChargingRecords> chargingRecords = chargingRecordsService.listByIds(Arrays.asList(chargingRecordsIds));
        List<ChargingRecords> unpaidChargingRecords = new ArrayList<>(); // 创建未支付账单列表
        String chargeOrderNumber = null;
        for (ChargingRecords chargingRecord : chargingRecords) {
            Integer paymentStatus = Integer.valueOf(chargingRecord.getStatus());
            // 检查账单是否已支付
            if (paymentStatus != 1) {
                continue; // 如果已支付，则跳过这个账单
            }

            Long money = chargingRecord.getConsumptionAmount();
            if (money != null) {
                totalMoney = totalMoney + money;
            }
            unpaidChargingRecords.add(chargingRecord); // 将未支付的账单添加到列表
            chargeOrderNumber = chargingRecord.getChargeOrderNumber();
        }

        if (unpaidChargingRecords.isEmpty()) {
            // 如果没有未支付的账单，则可以返回错误信息或者不创建订单
            // 例如，返回HTTP状态码400，附上错误信息
            resp.sendError(HttpServletResponse.SC_BAD_REQUEST, "No unpaid bills to process.");
            return;
        }

        if (ordersDto.getCouponId() != null) {
            couponId = ordersDto.getCouponId();
            Coupon coupon = couponService.getOne(Wrappers.lambdaQuery(Coupon.class)
                    .eq(Coupon::getStatus, 0)
                    .eq(Coupon::getId, ordersDto.getCouponId()));
            totalMoney = totalMoney - coupon.getAmount();
        }

        orders.setId(newId);
        orders.setItems(String.valueOf(items));
        orders.setTotal(totalMoney);
        orders.setCreateTime(new Date());
        orders.setItems(chargeOrderNumber);

        orders.setStatus(0);
        ordersServiceImpl.save(orders);

        String form = pay(orders);
        if (form == null) {
            throw new RemoteException("订单的金额总金额为0,请检查你所选中的账单是否被支付");
        }
        LoginUser loginUser = getLoginUser();
        userId = loginUser.getUserId();
        resp.setContentType("text/html;charset=" + CHARSET);
        // 将完整表单html输出到页面
        PrintWriter writer = resp.getWriter();
        writer.write(form);
        writer.flush();
        writer.close();
    }


    @CrossOrigin
    public String pay(Orders orders) throws IOException {
        if (orders.getTotal() == null || orders.getTotal() == 0) {
            return null;
        }
        Long temp = orders.getTotal();
        BigDecimal total = new BigDecimal(temp / 100);
        AliPay aliPay = new AliPay();
        aliPay.setOrderNum(orders.getId());//订单编号
        aliPay.setSubject(orders.getItems());//支付名称
        aliPay.setTotalPrice(total);//订单金额

        //1.创建Client，通用sdk提供的client，负责调用支付宝的api
        AlipayClient alipayClient = new DefaultAlipayClient(GATEWAY_URL, aliPayConfig.getAppId(),
                aliPayConfig.getAppPrivateKey(), FORMAT, CHARSET, aliPayConfig.getAlipayPublicKey(),
                SIGN_TYPE);
        //2.创建alipay请求并设置request参数
        AlipayTradePagePayRequest tradePagePayRequest = new AlipayTradePagePayRequest();
        tradePagePayRequest.setReturnUrl(aliPayConfig.getReturnUrl());
        tradePagePayRequest.setNotifyUrl(aliPayConfig.getNotifyUrl());
        JSONObject bizContent = new JSONObject();
        bizContent.set("out_trade_no", aliPay.getOrderNum());
        bizContent.set("total_amount", aliPay.getTotalPrice());
        bizContent.set("subject", aliPay.getSubject());
        bizContent.set("product_code", "FAST_INSTANT_TRADE_PAY");//固定配置
        tradePagePayRequest.setBizContent(bizContent.toString());
        tradePagePayRequest.setReturnUrl("");
        tradePagePayRequest.setBizContent(bizContent.toString());
        //执行请求，拿到响应结果，返回给游览器
        String form = "";

        try {
            //调用sdk生成表单
            form = alipayClient.pageExecute(tradePagePayRequest)
                    .getBody();
        } catch (Exception e) {
            if (e instanceof AlipayApiException) {
                System.out.println("业务异常");
            }
            e.printStackTrace();

        }
        return form;

    }

    @Anonymous
    @CrossOrigin
    @PostMapping("/notify")
    public void payNotify(HttpServletRequest req) throws AlipayApiException {
        if (req.getParameter("trade_status")
                .equals("TRADE_SUCCESS")) {
            System.out.println("==========支付宝异步回调========");
            Map<String, String> params = new HashMap<>();
            Map<String, String[]> reqParams = req.getParameterMap();
            for (String key : reqParams.keySet()) {
                params.put(key, req.getParameter(key));
                System.out.println(key + "=" + req.getParameter(key));
            }

            String outTradeNo = params.get("out_trade_no");
            String gmtPayment = params.get("gmt_payment");
            String alipayTradeNo = params.get("trade_no");

            String sign = params.get("sign");
            String content = AlipaySignature.getSignCheckContentV1(params);
            //验证签名
            boolean checkSignature = AlipaySignature
                    .rsa256CheckContent(content, sign,
                            aliPayConfig.getAlipayPublicKey(),
                            CHARSET);
            //支付宝验签
            if (checkSignature) {
                //验签通过
                System.out.println("交易名称: " + params.get("subject"));
                System.out.println("交易状态: " + params.get("trade_status"));
                System.out.println("支付宝交易凭证号: " + params.get("trade_no"));
                System.out.println("商户订单号: " + params.get("out_trade_no"));
                System.out.println("交易金额: " + params.get("total_amount"));
                System.out.println("买家在支付宝唯一id: " + params.get("buyer_id"));
                System.out.println("买家付款时间: " + params.get("gmt_payment"));
                System.out.println("买家付款金额: " + params.get("buyer_pay_amount"));

                //修改订单状态
                Orders orders = ordersServiceImpl.getById(params.get("out_trade_no"));
                orders.setStatus(2);
                orders.setPayNo(IdUtil.getSnowflakeNextId());
                orders.setPayTime(new Date());
                ordersServiceImpl.updateById(orders);
                for (ChargingRecords chargingRecords : chargingRecordsService.listByIds(Arrays.asList(chargingRecordsIds))) {
                    chargingRecords.setStatus("0");
                    chargingRecords.setPaymentMethod("支付宝");
                    chargingRecordsService.updateById(chargingRecords);
                }


                customerCouponsService.update(Wrappers.lambdaUpdate(CustomerCoupons.class)
                        .eq(CustomerCoupons::getCouponId, couponId)
                        .eq(CustomerCoupons::getCustomId,userId )
                        .set(CustomerCoupons::getStatus, 1));
            }

        }
    }

}
